// xmlrpc.cpp
//
// Copyright (c) Ivan Kelly 2008. All rights reserved.
//
#include <utf.h>
#include "xmlrpc.h"

using namespace XmlRpc;


EXPORT_C CXmlRpcResult::CXmlRpcResult()
	{
	iErrorCode = KErrNone;
	iResult = NULL;
	}

EXPORT_C CXmlRpcResult::~CXmlRpcResult()
	{
	delete iResult;
	}

EXPORT_C TInt CXmlRpcResult::ErrorCode()
	{
	return iErrorCode;
	}

EXPORT_C void CXmlRpcResult::SetErrorCode(TInt aErrorCode)
	{
	iErrorCode = aErrorCode;
	}

EXPORT_C const CValue* CXmlRpcResult::Result()
	{
	return iResult;
	}

EXPORT_C void CXmlRpcResult::SetResult(const CValue* aResult)
	{
	iResult = aResult;
	}

_LIT(KAmp, "&amp;");
_LIT(KQuot, "&quot;");
_LIT(KApos, "&apos;");
_LIT(KLt, "&lt;");
_LIT(KGt, "&gt;");

struct TXmlEntity {
	const TDesC& iEntity;
	TText16 iCharacter;
	};

const static TXmlEntity KEntities[] =
	{
	{KAmp, '&'},
	{KQuot, '"'},
	{KApos, '\''},
	{KLt, '<'},
	{KGt, '>'}
	};

EXPORT_C void XmlEncoding::DecodeL(const TDesC8& aInputString, RBuf& aOutputString)
	{
	HBufC16 *buf = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aInputString);
	aOutputString.Close();
	aOutputString.Assign(buf);

	for (TInt i = 0; i < sizeof(KEntities)/sizeof(TXmlEntity); i++)
		{
		TPtrC ptr(&KEntities[i].iCharacter, 1);
		
		while (ETrue)
			{
			TInt index = aOutputString.FindF(KEntities[i].iEntity);
			if (index < 0)
				break;
			aOutputString.Replace(index, KEntities[i].iEntity.Length(), ptr);
			}
		}
	}

EXPORT_C void XmlEncoding::EncodeL(const TDesC& aInputString, RBuf8& aOutputString)
	{
	RBuf in;
	
	in.CreateL(aInputString.Length());
	in.Copy(aInputString);
	CleanupClosePushL(in);

	for (TInt i = 0; i < sizeof(KEntities)/sizeof(TXmlEntity); i++)
		{
		TPtrC ch(&KEntities[i].iCharacter, 1);

		TInt offset = 0;
		TPtrC inputString = in.Mid(0);

		while (ETrue)
			{
			TInt index = inputString.Find(ch);
			if (index < 0)
				break;
			if (in.MaxLength() < (in.Length() + KEntities[i].iEntity.Length()))
				in.ReAllocL(in.MaxLength() + KEntities[i].iEntity.Length());
			const TDesC& x = KEntities[i].iEntity;
			in.Replace(offset + index, 1, KEntities[i].iEntity);
			offset += index+1;
			inputString.Set(in.Mid(offset));
			}
		}
		
	HBufC8 *buf = CnvUtfConverter::ConvertFromUnicodeToUtf8L(in);
	aOutputString.Close();
	aOutputString.Assign(buf);
	CleanupStack::PopAndDestroy(&in);
	}
